package br.jm.amanaje.dao;

import java.util.ArrayList;
import java.util.List;

import org.apache.cayenne.BaseContext;
import org.apache.cayenne.ObjectContext;
import org.apache.cayenne.exp.ExpressionFactory;
import org.apache.cayenne.query.SelectQuery;
import org.apache.cayenne.query.SortOrder;

import br.jm.amanaje.model.TipoQualificacao;
import br.jm.amanaje.model.Usuario;

public class UsuarioDAO {
	
	private ObjectContext context;
	private TipoQualificacaoDAO tipoDao;
	
	public UsuarioDAO() {
		this.context = BaseContext.getThreadObjectContext();
		this.tipoDao = new TipoQualificacaoDAO(context);
	}
	
	public void criar(Usuario usuario, int[] niveisQualificacoes) {
		this.context.registerNewObject(usuario);
		for (int nivel : niveisQualificacoes) {
			TipoQualificacao tipo = this.tipoDao.recuperarPorNivel(nivel);
			usuario.addToQualificacoes(tipo);
		}
		this.context.commitChanges();
	}
	
	public boolean atualizar(Usuario usuario, int[] niveisQualificacoes) {
		Usuario usuarioCommited = recuperar(usuario.getIdentidade());
		if (usuarioCommited == null) return false;
		
		List<TipoQualificacao> listaCursos = new ArrayList<TipoQualificacao>();
		listaCursos.addAll(usuarioCommited.getQualificacoes());
		
		for (TipoQualificacao curso : listaCursos)
			usuarioCommited.removeFromQualificacoes(curso);
		for (int nivel : niveisQualificacoes) 
			usuarioCommited.addToQualificacoes(this.tipoDao.recuperarPorNivel(nivel));
		
		usuarioCommited.merge(usuario);
		this.context.commitChanges();
		return true;
	}

	public boolean remover(Usuario usuario) {
		Usuario usuarioCommited = recuperar(usuario.getIdentidade());
		if (usuarioCommited == null) return false;
		
		List<TipoQualificacao> listaCursos = new ArrayList<TipoQualificacao>();
		listaCursos.addAll(usuarioCommited.getQualificacoes());
		
		for (TipoQualificacao curso : listaCursos)
			usuarioCommited.removeFromQualificacoes(curso);
		
		this.context.deleteObject(usuarioCommited);
		this.context.commitChanges();
		return true;
	}
	
	@SuppressWarnings("unchecked")
	public Usuario recuperar(String identidade) {
		SelectQuery query = new SelectQuery(Usuario.class,
				ExpressionFactory.matchExp(Usuario.IDENTIDADE_PROPERTY, identidade));
		List<Usuario> listaRecuperada = this.context.performQuery(query);
		return listaRecuperada != null && (! listaRecuperada.isEmpty())  ?
				(Usuario) listaRecuperada.get(0) : null;
	}
	
	@SuppressWarnings("unchecked")
	public List<Usuario> recuperarLista() {
		SelectQuery query = new SelectQuery(Usuario.class);
		query.addOrdering(Usuario.NOME_PROPERTY, SortOrder.ASCENDING);
		return this.context.performQuery(query);
	}
}
